package top.cardone.validator;

import com.google.common.collect.Maps;
import com.google.common.collect.Table;
import lombok.Setter;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import top.cardone.context.ApplicationContextHolder;
import top.cardone.context.util.TableUtils;
import top.cardone.core.util.func.Func4;

import java.util.Map;

/**
 * Created by Administrator on 2016/9/19.
 */
public class ValidatorImpl implements top.cardone.validator.Validator {
	@Setter
	private String beanIdSuffix = "ValidatorFunc";
	@Setter
	private String rulesKeyName = "rules";
	@Setter
	private String messagesKeyName = "messages";

	@Override
	public Map<String, String> validate(String validatorFile, Map<String, Object> map, boolean cacheValidatorTable) {
		return this.validate(TableUtils.newTable(validatorFile, cacheValidatorTable), map);
	}

	@Override
	public Map<String, String> validate(String validatorFile, Map<String, Object> map) {
		return this.validate(validatorFile, map, true);
	}

	@Override
	public Map<String, String> validate(Table<String, String, Map<String, Object>> validatorTable, Map<String, Object> map) {
		return this.validate(Maps.newHashMap(validatorTable.row(this.rulesKeyName)), Maps.newHashMap(validatorTable.row(this.messagesKeyName)), map);
	}

	@Override
	public Map<String, String> validate(Map<String, Object> rules, Map<String, Object> messages, Map<String, Object> map) {
		Map<String, String> errorMap = Maps.newHashMap();

		if (MapUtils.isEmpty(rules)) {
			return errorMap;
		}

		for (Map.Entry<String, Object> ruleEntry : rules.entrySet()) {
			if (!(ruleEntry.getValue() instanceof Map)) {
				continue;
			}

			Map<String, Object> ruleMap = (Map<String, Object>) ruleEntry.getValue();

			if (MapUtils.isEmpty(ruleMap)) {
				continue;
			}

			for (Map.Entry<String, Object> valEntry : ruleMap.entrySet()) {
				Object message = null;

				Object messagesObject = messages.get(ruleEntry.getKey());

				if (messagesObject instanceof Map) {
					message = MapUtils.getObject((Map<String, Object>) messagesObject, valEntry.getKey());
				}

				String beanId = valEntry.getKey() + beanIdSuffix;

				Func4<String, Map<String, Object>, String, Object, Object> func4 = ApplicationContextHolder.getBean(Func4.class, beanId);

				if (func4 == null) {
					continue;
				}

				String newMessage = func4.func(map, ruleEntry.getKey(), valEntry.getValue(), message);

				if (StringUtils.isNotBlank(newMessage)) {
					errorMap.put(ruleEntry.getKey(), newMessage);

					break;
				}
			}
		}

		return errorMap;
	}

	@Override
	public Map<String, String> validate(Map<String, Map<String, Object>> validatorTable, Map<String, Object> map) {
		return this.validate(Maps.newHashMap(validatorTable.get(this.rulesKeyName)), Maps.newHashMap(validatorTable.get(this.messagesKeyName)), map);
	}
}